package com.upcode.weighing.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.upcode.weighing.domain.SysRes;
import com.upcode.weighing.mapper.SysResMapper;
import com.upcode.weighing.service.MenuTreeService;
import com.upcode.weighing.service.SysResService;
import com.upcode.weighing.vo.add.SysResAddVo;
import com.upcode.weighing.vo.del.BaseDelVo;
import com.upcode.weighing.vo.edit.ButtonEditVo;
import com.upcode.weighing.vo.edit.SysResEditVo;
import com.upcode.weighing.vo.req.PageReqVo;
import com.upcode.weighing.vo.resp.PageRespVo;
import com.upcode.weighing.vo.resp.pc.ButtonVo;
import com.upcode.weighing.vo.resp.pc.MenuTreeVo;
import com.upcode.weighing.vo.resp.pc.SysResVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.upcode.weighing.common.constant.BillConstants.*;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author alex
 * @since 2019-04-10
 */
@Service
@Transactional
public class SysResServiceImpl extends ServiceImpl<SysResMapper, SysRes> implements SysResService {
    @Autowired
    private MenuTreeService menuTreeService;
    @Autowired
    private SysResMapper sysResMapper;

    //菜单管理分页列表
    @Override
    public PageRespVo<SysResVo> selectPageList(PageReqVo<SysResVo> vo) {
        Page<SysResVo> pageInfo = new Page<>(vo.getPage().getCurrentPage(), vo.getPage().getPageSize());//创建分页
        PageRespVo<SysResVo> pageRespVo = new PageRespVo<SysResVo>();
        IPage<SysResVo> iPage = sysResMapper.selectPageList(pageInfo, vo.getParams());
        pageRespVo.setPage(iPage);
        return pageRespVo;
    }

    //查询菜单是否存在
    @Override
    public int checkRes(String permission) {
        return sysResMapper.checkRes(permission);
    }

    //添加菜单
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public int addRes(SysResAddVo vo) {
        SysRes r = new SysRes();
        r.setId(IdWorker.getId());//资源ID
        r.setPid(vo.getPid());//父级ID
        r.setName(vo.getName());//菜单名称
        r.setPermission(vo.getPermission());//资源权限名称(自定义,不能重复)
        r.setUrl(vo.getUrl());//url(路径链接:当前指在vue中的路由名称)
        r.setSortNum(vo.getSortNum());//排序
        r.setAttach(ZI_YUAN_TYPE_CAIDAN);//1:pc端，2:app端 当前为PC端
        r.setIcon1(vo.getIcon1());//PC菜单图片
        r.setIcon2("");//APP菜单图片 没有设置无
        r.setPids(vo.getPids());//TreeTable排序(所有父级ID集合，多个父级ID用逗号隔开,例如(0,1,3))
        r.setType(ZI_YUAN_WEIZHI_PC);//1:菜单2 :按钮
        r.setVueKey(vo.getVueKey());//key值
        r.setDes(vo.getDes());//备注（备注当前菜单属于几级菜单）
        r.setStatus(DELETE_TYPE_NOT_DELETE);//状态1 可用 0 不可用 -1: 删除 当前默认为可用 1
        r.setCreateTime(LocalDateTime.now());//创建时间
        r.setUpdateTime(LocalDateTime.now());//修改时间
        return sysResMapper.addRes(r);
    }

    //获取所有菜单
    @Override
    public List<SysRes> getRes() {
        List<SysRes> list = sysResMapper.getRes();
        List<SysRes> list1 = new ArrayList<SysRes>();
        for (SysRes r : list) {
            if (r.getPid() == 0) {
                list1.add(r);
            }
        }
        for (SysRes r : list1) {
            r.setChildRes(getChild(r.getId(), list));
        }
        return list1;
    }

    //修改菜单
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public int editRes(SysResEditVo vo) {
        SysRes r = new SysRes();
        r.setId(vo.getId());//要修改的菜单的ID
        r.setName(vo.getName());//菜单名称
        r.setPermission(vo.getPermission());//菜单编码
        r.setUrl(vo.getUrl());//url 路由中的path
        r.setDes(vo.getDes());//描述
        r.setSortNum(vo.getSortNum());//排序
        r.setVueKey(vo.getVueKey());//key值
        r.setIcon1(vo.getIcon1());//图标
        r.setUpdateTime(LocalDateTime.now());//修改时间
        return sysResMapper.editRes(r);
    }

    //删除菜单
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public int delRes(BaseDelVo vo) {
        return sysResMapper.delRes(vo.getIds());
    }

    //获取一级菜单列表
    @Override
    public List<SysResVo> getParentResList() {
        return sysResMapper.getParentResList();
    }

    //根据一级菜单获取二级菜单
    @Override
    public List<SysResVo> getChildList(Long pId) {
        return sysResMapper.getChildList(pId);
    }

    //添加按钮
    @Override
    public int addButton(SysResAddVo vo) {
        SysRes r = new SysRes();
        r.setId(IdWorker.getId());//资源ID
        r.setPid(vo.getPid());//父级ID
        r.setName(vo.getName());//菜单名称
        r.setPermission(vo.getPermission());//资源权限名称(自定义,不能重复)
        r.setUrl(vo.getUrl());//url(路径链接:当前指在vue中的路由名称)
        r.setSortNum(vo.getSortNum());//排序 当前设置为1
        r.setAttach(ZI_YUAN_WEIZHI_PC);//1:pc端，2:app端 当前为PC端
        r.setIcon1(vo.getIcon1());//PC菜单图片
        r.setIcon2("");//APP菜单图片 没有设置无
        r.setPids(vo.getPids());//TreeTable排序(所有父级ID集合，多个父级ID用逗号隔开,例如(0,1,3))
        r.setType(ZI_YUAN_TYPE_BUTTON);//1:菜单2 :按钮
        r.setVueKey(vo.getVueKey());//key值
        r.setDes(vo.getDes());//备注（备注当前菜单属于几级菜单）
        r.setStatus(DELETE_TYPE_NOT_DELETE);//状态1 可用 0 不可用 -1: 删除 当前默认为可用 1
        r.setCreateTime(LocalDateTime.now());//创建时间
        r.setUpdateTime(LocalDateTime.now());//修改时间
        return sysResMapper.addRes(r);
    }

    //获取按钮信息
    @Override
    public ButtonVo getButton(Long id) {
        return sysResMapper.getButton(id);
    }

    //修改按钮
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public int updateButton(ButtonEditVo vo) {
        SysRes r = new SysRes();
        r.setId(vo.getId());//id
        r.setName(vo.getName());//名称
        r.setPermission(vo.getPermission());//编码
        r.setDes(vo.getDes());//描述
        r.setSortNum(vo.getSortNum());//排序
        r.setVueKey(vo.getVueKey());//key
        r.setIcon1(vo.getIcon());//图标
        r.setUpdateTime(LocalDateTime.now());//修改时间
        return sysResMapper.updateButton(r);
    }

    //删除按钮
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    @Override
    public int delButton(BaseDelVo vo) {
        return sysResMapper.delButton(vo.getIds());
    }

    //获取左侧菜单
    @Override
    public List<SysRes> getLeftRes() {
        List<SysRes> list = sysResMapper.getLeftRes();
        List<SysRes> list1 = new ArrayList<SysRes>();
        for (SysRes r : list) {
            if (r.getPid() == 0) {
                list1.add(r);
            }
        }
        for (SysRes r : list1) {
            r.setChildRes(getChild(r.getId(), list));
        }
        return list1;
    }

    //检查标识是否重复
    @Override
    public int checkVueKey(String vueKey) {
        return sysResMapper.checkVueKey(vueKey);
    }

    //二级菜单下不允许再添加菜单
    @Override
    public Long checkChild(Long id) {
        return sysResMapper.checkChild(id);
    }

    //获取要修改的菜单信息
    @Override
    public SysRes getEditRes(Long id) {
        return sysResMapper.getEditRes(id);
    }

    @Override
    public List<MenuTreeVo> menuTreeByUserId(Long userId) {
        List<SysRes> menuList = sysResMapper.listByUserId(userId);
        if (menuList.size() > 0) {
            List<MenuTreeVo> parentList = menuList.stream()
                    .filter(item -> 0 == item.getPid())
                    .map(item -> new MenuTreeVo(item.getId(), item.getPid(), item.getName(), item.getPermission(), item.getUrl(), item.getSortNum(), item.getIcon1(), item.getIcon2(), item.getType(), item.getDes()))
                    .sorted(Comparator.comparingInt(item -> Optional.ofNullable(item.getSortNum()).orElse(0)))
                    .collect(Collectors.toList());
            parentList.forEach(item -> {
                //封装菜单树
                menuTreeService.menuTree(item, menuList);
            });
            return parentList;
        }
        return null;
    }

    //递归查找子菜单
    private List<SysRes> getChild(Long id, List<SysRes> list) {
        List<SysRes> childList = new ArrayList<SysRes>();
        for (SysRes r : list) {
            if (r.getPid().equals(id)) {
                childList.add(r);
            }
        }
        for (SysRes r : childList) {
            r.setChildRes(getChild(r.getId(), list));
        }
        if (childList.size() == 0) {
            return null;
        }
        return childList;
    }
}
